<?php

/**
 * Framework_Session
 *
 * @author      Ian Szewczyk <roamzero@gmail.com>
 * @copyright   (c) 2007 Ian Szewczyk. All rights reserved.
 * @license     http://www.opensource.org/licenses/bsd-license.php
 * @package Framework
 * @filesource
 */



//define('Auth_OpenID_RAND_SOURCE', null);
//require_once 'Auth/OpenID/Server.php';



 /**
  * Framework_Session
  *
  * Our base session class as a singleton. Handles creating the session,
  * writing to the session variable (via overloading) and destroying the
  * session.
  *
  * @author Ian Szewczyk <roamzero@gmail.com>
  * @package Framework
  */
class Framework_Session
{
	/**
	 * $instance
	 *
	 * Instance variable used for singleton pattern. Stores a single instance
	 * of Framework_Session.
	 *
	 * @access private
	 * @var mixed $instance
	 */
	private static $instance;

	/**
     * $max
     *
     * @access 		public
	 * @var 		integer 	$max		
     */
	public $max = 172800; // 2 days

	/**
     * $updateFields
     *
     * @access 		public
     * @var 		array 		$updateFields 	
     */
	public $updateFields;

	/**
     * $user
     *
     * @access 		public
     * @var 		boolean 	$isNew 		
     */
	public $isNew = false;

	/**
     * $sessionTable
     *
     * @access 		public
     * @var 		Framework_Table_Common 		$sessionTabler 		
     */
	public $sessionTable;

	/**
	 * $sessionID
	 *
	 * The session ID assigned by PHP (usually a 32 character alpha-numeric
	 * string).
	 *
	 * @access public
	 * @var string $sessionID
	 */
	public $sessionID = '';

	/**
	 * __construct
	 *
	 * Starts the session and sets the sessionID for the class.
	 *
	 * @access public
	 * @return void
	 */
	public function __construct()
	{
		$this->sessionTable = Framework_DB::tableFactory('Session');
		
		session_set_save_handler(
		array(&$this, 'open'),
		array(&$this, 'close'),
		array(&$this, 'read'),
		array(&$this, 'write'),
		array(&$this, 'dbDestroy'),
		array(&$this, 'gc'));

		// Change session.gc_probability
		ini_set('session.gc_probability',10);
		ini_set('session.gc_divisor',100);

		if (ini_get('session.auto_start') == 0) {
			session_start();
		}
		
		 
		

		$this->sessionID = session_id();
		
		
	}

	/**
	 * singleton
	 *
	 * Implementation of the singleton pattern. Returns a sincle instance
	 * of the session class.
	 *
	 * @author Ian Szewczyk <roamzero@gmail.com>
	 * @return mixed Instance of session
	 */
	public static function singleton()
	{
		if (!isset(self::$instance)) {
			$className = __CLASS__;
			self::$instance = new $className;
		}

		return self::$instance;
	}

	/**
	 * destroy
	 *
	 * Destroys the session
	 *
	 * @author Ian Szewczyk <roamzero@gmail.com>
	 * @access public
	 * @return void
	 */
	public function destroy()
	{
		foreach ($_SESSION as $var => $val) {
			session_unregister($var);
		}

		session_destroy();
	}

	/**
	 * __clone
	 *
	 * Disable PHP5's cloning method for session so people can't make copies
	 * of the session instance.
	 *
	 * @author Ian Szewczyk <roamzero@gmail.com>
	 * @access public
	 * @return void
	 */
	public function __clone()
	{
		trigger_error('Clone is not allowed for '.__CLASS__,E_USER_ERROR);
	}

	/**
	 * The Following functions are used to interface the session handling with the database
	 *
	 *
	 */
	public function open($sessPath, $sessName){
		return true;
	}

	public function close(){
		return true;
	}

	public function read($sessID){
		$currentTime = time();
		$queryArray = array(
			'sqlKey' => 'getData',
			'params' => array($sessID)
		);
		
		$result = $this->sessionTable->select($queryArray);
		
		if(!is_array($result)) {
			$result = $this->sessionTable->insert(array('sessionKey' => $sessID, 'dateTouched' => $currentTime));
			$this->isNew = true;
			return '';
		} else {
			$this->sessionTable->update(array('dateTouched' => $currentTime),'sessionKey = "'.$sessID.'"');
			return $result['sessData'];
		}
	}

	public function write($sessID, $data){
		
		
		$this->updateFields['sessData'] = $data;
		$this->updateFields['dateTouched'] = time();
		
		$result = $this->sessionTable->update($this->updateFields, 'sessionKey = "'.$sessID.'"');
		

		return true;
	}

	public function dbDestroy($sessID){
		
		$this->sessionTable->delete('sessionKey = "'.$sessID.'"');
		return true;
	}

	public function gc(){
		$old = time() - $this->max;
		$this->sessionTable->delete('dateTouched < "'.$old.'"');
		return true;
	}


	public function updateField($field,$value){
		$this->updateFields[$field] = mysql_real_escape_string($value);
	}

	/**
	 * __get($var)
	 *
	 * Returns the requested session variable.
	 *
	 * @access public
	 * @return mixed Returns the value of $_SESSION[$var]
	 * @see Framework_Session::__set()
	 */
	public function __get($var)
	{

		if (!isset($_SESSION[$var])) {
			$_SESSION[$var] = null;
		}

		return $_SESSION[$var];
	}

	/**
	 * __set
	 *
	 * Using PHP5's overloading for setting and getting variables we can
	 * use $session->var = $val and have it stored in the $_SESSION
	 * variable. To set an email address, for instance you would do the
	 * following:
	 *
	 * <code>
	 * $session->email = 'user@example.com';
	 * </code>
	 *
	 * This doesn't actually store 'user@example.com' into $session->email,
	 * rather it is stored in $_SESSION['email'].
	 *
	 * @param string $var
	 * @param mixed $val
	 * @see Framework_Session::__get()
	 * @link http://us3.php.net/manual/en/language.oop5.overloading.php
	 * @return boolean
	 */
	public function __set($var,$val)
	{
		return ($_SESSION[$var] = $val);
	}


}
?>